package com.app.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.*;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.app.annotion.RedisLockAnnotation;
import com.app.common.Result;
import com.app.common.SystemConstant;
import com.app.config.RedisService;
import com.app.enums.StatusCodeEnum;
import com.app.mapper.*;
import com.app.model.*;
import com.app.service.*;
import com.app.utils.*;
import com.app.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static cn.hutool.crypto.digest.DigestUtil.md5Hex;
import static com.app.common.SystemConstant.DEFAULT_PDF_SERVICE_URL;

@Slf4j
@RestController
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private AdminUserService adminUserService;
    @Autowired
    private InviteRecordService inviteRecordService;
    @Autowired
    private RedisService redisService;
    @Resource
    private SMSUtils smsUtils;
    @Autowired
    private AddressService addressService;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private CityMapper cityMapper;
    @Autowired
    private AreaMapper areaMapper;
    @Autowired
    private CustomerServiceService customerServiceService;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private IntegralOrderMapper inviteOrderMapper;
    @Autowired
    private TransferRecordsMapper transferRecordsDao;
    @Autowired
    private VoucherRecordMapper voucherRecordMapper;
    @Autowired
    private InviteRecordMapper inviteRecordMapper;
    @Autowired
    private IntegralRecordMapper integralRecordMapper;

    /**
     * 用户列表
     *
     * @param ifVip      1vip 2粉丝
     * @param page
     * @param limit
     * @param keyword
     * @param areaId
     * @param request
     * @param isBusiness 1商家 2不是商家
     * @return
     */
    @GetMapping("/userList")
    public Result<Object> userList(Integer ifVip, Integer page, Integer limit, String keyword, String areaId, HttpServletRequest request, Integer isBusiness,Integer roleId,
                                   Integer identity,String beginTime,String endTime) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(405, "token不存在");
        }
        String userId = TokenUtils.verify(token);
        AdminUserModel user = adminUserService.getById(Integer.parseInt(userId));
        if (user == null) {
            return Result.error(405, "用户不存在");
        }
        UserVo list = userService.getList(page, limit, keyword, user, areaId, identity,beginTime,endTime,ifVip);
        return Result.success(list);
    }


    @GetMapping("/getUserAllCount")
    public Result<Object> getUserAllCount(Integer ifVip,String keyword, String areaId, HttpServletRequest request,
                                          Integer identity,String beginTime,String endTime){
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(405, "token不存在");
        }
        String userId = TokenUtils.verify(token);
        AdminUserModel user = adminUserService.getById(Integer.parseInt(userId));
        if (user == null) {
            return Result.error(405, "用户不存在");
        }

        JSONObject object = userService.getUserAllCount(keyword, user, areaId, identity,beginTime,endTime);
        return Result.success(object);
    }


    //删除用户
    @GetMapping("/deleteUser")
    public Result<Object> deleteUser(Integer id, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(405, "token不存在");
        }
        String userId = TokenUtils.verify(token);
        AdminUserModel user = adminUserService.getById(Integer.parseInt(userId));
        if (user == null) {
            return Result.error(405, "用户不存在");
        }
        userService.removeById(id);
        return Result.success("");//删除成功
    }


    /**
     * 用户详情 ----  当前用户可使用  券  和  积分  以及 邀请会员获得的券
     * @param userid
     * @param request
     * @return
     */
    @GetMapping("/getUserVoucherAndIntegral")
    public Result<Object> getUserVoucherAndIntegral(Integer userid, HttpServletRequest request){
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(405, "token不存在");
        }
        String userId = TokenUtils.verify(token);
        AdminUserModel user = adminUserService.getById(Integer.parseInt(userId));
        if (user == null) {
            return Result.error(405, "用户不存在");
        }
        QueryWrapper<UserModel> userModelQueryWrapper = new QueryWrapper<>();
        userModelQueryWrapper.select("voucher", "integral");
        userModelQueryWrapper.eq("id", userid);
        UserModel userModel = userMapper.selectOne(userModelQueryWrapper);

        BigDecimal inviteVip = voucherRecordMapper.sumVoucherAmountByUserIdAndTypeName(userid,"邀请好友");

        UserModel userInfo = userMapper.getUserInfoById(userid);

        UserModel supUserInfo = userMapper.getUserSuperiorById(userid);

        JSONObject object = new JSONObject();
        if (null == userModel){
            object.put("voucher",0);
            object.put("integral",0);
        }else {
            object.put("voucher",null != userModel.getVoucher() ? userModel.getVoucher() : 0);
            object.put("integral",null != userModel.getIntegral() ? userModel.getIntegral() : 0);
        }
        object.put("voucherVip",inviteVip);

        object.put("userInfo",userInfo);
        object.put("supUserInfo",supUserInfo);

        return Result.success(object);
    }


    //当前用户可使用  券  和  积分  以及 邀请会员获得的券   列表
    @GetMapping("/getUserVoucherAndIntegralList")
    public Result<Object> getUserVoucherAndIntegralList(HttpServletRequest request, Integer page, Integer limit,Integer userid,String type,String beginTime,String endTime){
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(405, "token不存在");
        }
        String userId = TokenUtils.verify(token);
        AdminUserModel user = adminUserService.getById(Integer.parseInt(userId));
        if (user == null) {
            return Result.error(405, "用户不存在");
        }
        if ("1".equals(type)){
            VoucherRecordVo vo = new VoucherRecordVo();
            QueryWrapper<VoucherRecordModel> qw = new QueryWrapper<>();
            qw.eq("user_id", userid);
            qw.orderByDesc("create_time");
            if (StrUtil.isNotBlank(beginTime) && StrUtil.isNotBlank(endTime)) {
                // 注意：这里的时间格式需要与数据库中的 TIMESTAMP 格式匹配
                qw.between("create_time", beginTime, endTime);
            }

            Page<VoucherRecordModel> page1 = new Page<>(page, limit);
            Page<VoucherRecordModel> voucherRecordModelPage = voucherRecordMapper.selectPage(page1, qw);
            vo.setList(voucherRecordModelPage.getRecords());
            vo.setCount((int) voucherRecordModelPage.getTotal());
            return Result.success(vo);
        }
        else if ("2".equals(type)){
            IntegralRecordVo vo = new IntegralRecordVo();

            QueryWrapper<IntegralRecordModel> qw = new QueryWrapper<>();
            qw.eq("user_id", userid);
            qw.orderByDesc("create_time");
            if (StrUtil.isNotBlank(beginTime) && StrUtil.isNotBlank(endTime)) {
                // 注意：这里的时间格式需要与数据库中的 TIMESTAMP 格式匹配
                qw.between("create_time", beginTime, endTime);
            }

            Page<IntegralRecordModel> page1 = new Page<>(page, limit);
            Page<IntegralRecordModel> voucherRecordModelPage = integralRecordMapper.selectPage(page1, qw);
            vo.setList(voucherRecordModelPage.getRecords());
            vo.setCount((int) voucherRecordModelPage.getTotal());
            return Result.success(vo);
        }
        else if ("3".equals(type)){
            VoucherRecordVo vo = new VoucherRecordVo();

            QueryWrapper<VoucherRecordModel> qw = new QueryWrapper<>();
            qw.eq("user_id", userid);
            qw.eq("type_name", "邀请好友");
            if (StrUtil.isNotBlank(beginTime) && StrUtil.isNotBlank(endTime)) {
                // 注意：这里的时间格式需要与数据库中的 TIMESTAMP 格式匹配
                qw.between("create_time", beginTime, endTime);
            }
            qw.orderByDesc("create_time");
            Page<VoucherRecordModel> page1 = new Page<>(page, limit);
            Page<VoucherRecordModel> voucherRecordModelPage = voucherRecordMapper.selectPage(page1, qw);
            vo.setList(voucherRecordModelPage.getRecords());
            vo.setCount((int) voucherRecordModelPage.getTotal());
            return Result.success(vo);
        }
        return Result.success(new ArrayList<>());
    }


    //详情

    /**
     * 用户详情
     *
     * @param id
     * @param type 1消费的券记录 2获得的券记录 3消费的积分的记录 4获得的积分的记录
     * @return
     */
    @GetMapping("/getUserById")
    public Result<Object> getUserInfo(Integer id, Integer type, String dateLimit, Integer page, Integer limit) throws Exception {
        UserModel userModel = userService.getById(id);
        if (StrUtil.isNotBlank(userModel.getAreaCode())) {
            List<String> list = JSON.parseObject(userModel.getAreaCode(), new TypeReference<List<String>>() {
            });
            userModel.setValue(list);
        }
        userModel.setOpenId(null);

        if (type == 1 || type == 2) {//1消费的券记录 voucherRecordsUse   2获得的券记录 voucherRecordsGet
            UserVVO userVVO = new UserVVO();
            Page<VoucherRecordModel> page1 = new Page<>(page, limit);
            QueryWrapper<VoucherRecordModel> vget = new QueryWrapper<VoucherRecordModel>()
                    .eq("user_id", id)
                    .like(type == 1, "voucher", "-%")
                    .like(type == 2, "voucher", "+%");
            if (StrUtil.isNotEmpty(dateLimit)) {
                DateLimitUtilVo dateLimitVo = CrmebDateUtil.getDateLimit(dateLimit);
                String startDate = cn.hutool.core.date.DateUtil.parse(dateLimitVo.getStartTime()).toDateStr();
                String endDate = DateUtil.parse(dateLimitVo.getEndTime()).toDateStr();
                vget.between("create_time", startDate, endDate);
            }

            Page<VoucherRecordModel> voucherRecordModelPage = voucherRecordMapper.selectPage(page1, vget);
            userVVO.setList(voucherRecordModelPage.getRecords());
            userVVO.setCount(voucherRecordModelPage.getTotal());
            return Result.success(userVVO);
        } else {//3消费的积分的记录  integralRecordsUse   4获得的积分的记录   integralRecordsGet
//            Page<IntegralRecordModel>  page2=  new Page<>(page,limit);
            UserDetialVO vo = new UserDetialVO();
            Page<IntegralRecordModel> page2 = new Page<>(page, limit);
            QueryWrapper<IntegralRecordModel> iGet = new QueryWrapper<IntegralRecordModel>()
                    .eq("user_id", id)
                    .like(type == 3, "integral", "-%")
                    .like(type == 4, "integral", "+%");
            if (StrUtil.isNotEmpty(dateLimit)) {
                DateLimitUtilVo dateLimitVo = CrmebDateUtil.getDateLimit(dateLimit);
                String startDate = cn.hutool.core.date.DateUtil.parse(dateLimitVo.getStartTime()).toDateStr();
                String endDate = DateUtil.parse(dateLimitVo.getEndTime()).toDateStr();
                iGet.between("create_time", startDate, endDate);
            }
//             inviteRecordMapper.selectPage(page2, iGet);
            Page<IntegralRecordModel> integralRecordModelPage = integralRecordMapper.selectPage(page2, iGet);
            vo.setList(integralRecordModelPage.getRecords());
            vo.setCount(integralRecordModelPage.getTotal());
            return Result.success(vo);
        }
//        //统计用户月消费-券(团购+商品兑换+转账)
//        Double orderCoupons = orderMapper.getMonthlyConsumption(userModel.getId());
//        Double inviteOrderCoupons = inviteOrderMapper.getMonthlyConsumption(userModel.getId());
//        Double transferCoupons = transferRecordsDao.getMonthlyConsumption(userModel.getId());
//        Double allCoupons = orderCoupons + inviteOrderCoupons + transferCoupons;
//        //统计用户月消费-积分(商品兑换)
//        Double inviteOrderPoints = inviteOrderMapper.getMonthlyPointsConsumption(userModel.getId());
//        userModel.setAllCoupons(allCoupons);
//        userModel.setInviteOrderPoints(inviteOrderPoints);

    }


    /**
     * 用户数据摘要
     *
     * @param id        id
     * @param type      类型
     * @param dateLimit 日期限制
     * @return {@link Result}<{@link Object}>
     * @throws Exception 例外
     */
    @GetMapping("userDataSummary")
    public Result<Object> userDataSummary(Integer id, Integer type, String dateLimit) throws Exception {
        UserModel userModel = userService.getById(id);
        if (StrUtil.isNotBlank(userModel.getAreaCode())) {
            List<String> list = JSON.parseObject(userModel.getAreaCode(), new TypeReference<List<String>>() {
            });
            userModel.setValue(list);
        }
        userModel.setOpenId(null);

        if (type == 1 || type == 2) {//1消费的券记录 voucherRecordsUse   2获得的券记录 voucherRecordsGet
            UserVVO userVVO = new UserVVO();

            QueryWrapper<VoucherRecordModel> vget = new QueryWrapper<VoucherRecordModel>()
                    .eq("user_id", id)
                    .like(type == 1, "voucher", "-%")
                    .like(type == 2, "voucher", "+%");
            if (StrUtil.isNotEmpty(dateLimit)) {
                DateLimitUtilVo dateLimitVo = CrmebDateUtil.getDateLimit(dateLimit);
                String startDate = cn.hutool.core.date.DateUtil.parse(dateLimitVo.getStartTime()).toDateStr();
                String endDate = DateUtil.parse(dateLimitVo.getEndTime()).toDateStr();
                vget.between("create_time", startDate, endDate);
            }

            List<VoucherRecordModel> benefitCoupon = voucherRecordMapper.selectList(vget);
            double sum = benefitCoupon.stream()
                    .map(VoucherRecordModel::getVoucher) // 获取每个 VoucherRecordModel 的 voucher
                    .map(voucher -> voucher.replaceAll("[^\\d.]", "")) // 使用正则表达式过滤掉非数字和非小数点字符
                    .filter(voucher -> !voucher.isEmpty()) // 过滤掉空字符串
                    .mapToDouble(Double::parseDouble) // 将字符串转换为 double
                    .sum(); // 对所有的 double 值求和

            return Result.success(sum);
        } else {//3消费的积分的记录  integralRecordsUse   4获得的积分的记录   integralRecordsGet
            UserDetialVO vo = new UserDetialVO();
            QueryWrapper<IntegralRecordModel> iGet = new QueryWrapper<IntegralRecordModel>()
                    .eq("user_id", id)
                    .like(type == 3, "integral", "-%")
                    .like(type == 4, "integral", "+%");
            if (StrUtil.isNotEmpty(dateLimit)) {
                DateLimitUtilVo dateLimitVo = CrmebDateUtil.getDateLimit(dateLimit);
                String startDate = cn.hutool.core.date.DateUtil.parse(dateLimitVo.getStartTime()).toDateStr();
                String endDate = DateUtil.parse(dateLimitVo.getEndTime()).toDateStr();
                iGet.between("create_time", startDate, endDate);
            }
            List<IntegralRecordModel> benefitCoupon = integralRecordMapper.selectList(iGet);
            double sum = benefitCoupon.stream()
                    .map(IntegralRecordModel::getIntegral) // 获取每个 VoucherRecordModel 的 voucher
                    .map(voucher -> voucher.replaceAll("[^\\d.]", "")) // 使用正则表达式过滤掉非数字和非小数点字符
                    .filter(voucher -> !voucher.isEmpty()) // 过滤掉空字符串
                    .mapToDouble(Double::parseDouble) // 将字符串转换为 double
                    .sum(); // 对所有的 double 值求和
            return Result.success(sum);
        }
    }


    //修改状态
    @GetMapping("/updateStatus")
    public Result<Object> updateStatus(Integer id, Integer status, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(405, "token不存在");
        }
        String userId = TokenUtils.verify(token);
        AdminUserModel user = adminUserService.getById(Integer.parseInt(userId));
        if (user == null) {
            return Result.error(405, "用户不存在");
        }
        userService.updateStatus(id, status);
        return Result.success("");//修改成功
    }

    /********************************************新的登录方法*******************************************************************/

    @GetMapping("/appletLogin")
    public Result appletLogin(Long userid){
        QueryWrapper<UserModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", userid);
        UserModel userModel = userService.getOne(queryWrapper);
        String token = TokenUtils.sign(userModel.getOpenId());
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", userModel);
        return Result.success(map);
    }


    @GetMapping("/getOpenid")
    public Object getOpenid(String code) throws LoginException {
        //获取openid
        String openid = WechatUtil.getOpenid(code);
        if (openid == null) {
            throw new LoginException("openid为空");
        }
        //根据openid查询用户信息
        QueryWrapper<UserModel> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("login_openid", openid);
        List<UserModel> userList = userMapper.selectList(userQueryWrapper);
        if (userList.isEmpty()) {
            return Result.error(405, "登录失效");
        } else {
            for (UserModel user : userList) {
                user.setOpenId(UUID.randomUUID().toString());
                user.setLastLoginTime(new Date());
                userMapper.updateById(user);
            }
            if (userList.size() > 1) {
                UserLoginVo userLoginVO = new UserLoginVo();
                userLoginVO.setUserlist(userList);
                return Result.success(userLoginVO);
            } else {
//                String token = TokenUtils.sign(userList.get(0).getOpenId());
                UserLoginVo userLoginVO = new UserLoginVo();
                userLoginVO.setUserlist(userList);
//                userLoginVO.setToken(token);
                return Result.success(userLoginVO);
            }
        }
    }

    //获取手机号
    @GetMapping("/getPhoneNew")
    public Result<Object> getPhoneNew(String mobileCode, String code, String inviteCode, HttpServletRequest request) throws Exception {
        //获取openid
        String openid = WechatUtil.getOpenid(code);
        if (openid == null) {
            return Result.error(201, "openid获取失败");
        }

        String phone = userService.getPhone(mobileCode);

        QueryWrapper<UserModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        List<UserModel> users = userService.list(queryWrapper);
        Map<String, Object> map = new HashMap<>();
        if (users.isEmpty()) {
            UserModel userModel = new UserModel();
            userModel.setPhone(phone);
            String endPhone = phone.substring(7, 11);
            userModel.setName("益联宝" + endPhone);//默认昵称
            userModel.setFaceUrl(SystemConstant.DEFAULT_FACE_URL);//默认头像
            userModel.setOpenId(openid);
            userModel.setLoginOpenid(openid);
            userModel.setCreateTime(CommonHelp.getNowTimestamp());
            userService.save(userModel);
            if (StrUtil.isNotBlank(inviteCode)) {
                //查询邀请人
                UserModel inviteUser = userService.getUserByInviteCode(inviteCode);
                if (inviteUser != null) {
                    //添加邀请记录
                    InviteRecordModel inviteRecordModel = new InviteRecordModel();
                    inviteRecordModel.setInviteId(inviteUser.getId());
                    inviteRecordModel.setQuiltInviteId(userModel.getId());
                    inviteRecordModel.setStatus(1);
                    inviteRecordModel.setCreateTime(CommonHelp.getNowTimestamp());
                    inviteRecordService.save(inviteRecordModel);
                }
            }

            String token = TokenUtils.sign(userModel.getOpenId());
            map.put("token", token);
            map.put("user", userModel);
            return Result.success(map);
        }else {
            UserModel user = users.get(0);
            user.setLastLoginTime(new Date());
            this.userService.updateById(user);
            String token = TokenUtils.sign(user.getOpenId());
            map.put("token", token);
            map.put("user", user);
            return Result.success(map);
        }
    }

    //获取手机号
    @GetMapping("/getPhone")
    public Result<Object> getPhone(String mobileCode, String code, String inviteCode, HttpServletRequest request) throws Exception {
        //获取openid
        String openid = WechatUtil.getOpenid(code);
        if (openid == null) {
            return Result.error(201, "openid获取失败");
        }
        UserModel user = userService.getUserByOpenid(openid);
        Map<String, Object> map = new HashMap<>();
        if (user == null) {
            String phone = userService.getPhone(mobileCode);
            QueryWrapper<UserModel> qw = new QueryWrapper<>();
            qw.eq("phone", phone);
            UserModel userModel = userService.getOne(qw);
            if (userModel == null) {
                userModel = new UserModel();
                userModel.setPhone(phone);
                String endPhone = phone.substring(7, 11);
                userModel.setName("益联宝" + endPhone);//默认昵称
                userModel.setFaceUrl(SystemConstant.DEFAULT_FACE_URL);//默认头像
                userModel.setOpenId(openid);
                userModel.setLoginOpenid(openid);
                userModel.setCreateTime(CommonHelp.getNowTimestamp());
                userService.save(userModel);
                if (StrUtil.isNotBlank(inviteCode)) {
                    //查询邀请人
                    UserModel inviteUser = userService.getUserByInviteCode(inviteCode);
                    if (inviteUser != null) {
                        //添加邀请记录
                        InviteRecordModel inviteRecordModel = new InviteRecordModel();
                        inviteRecordModel.setInviteId(inviteUser.getId());
                        inviteRecordModel.setQuiltInviteId(userModel.getId());
                        inviteRecordModel.setStatus(1);
                        inviteRecordModel.setCreateTime(CommonHelp.getNowTimestamp());
                        inviteRecordService.save(inviteRecordModel);
                    }
                }
            }
            String token = TokenUtils.sign(userModel.getOpenId());
            map.put("token", token);
            map.put("user", userModel);
            return Result.success(map);
        } else {
            user.setLastLoginTime(new Date());
            this.userService.updateById(user);
            String token = TokenUtils.sign(user.getOpenId());
            map.put("token", token);
            map.put("user", user);
            return Result.success(map);
        }
    }

    //为测试写的获取token的方法
//    @GetMapping("/getToken")
    public Result<Object> test(@RequestParam("userId") Integer userId) {
        UserModel userInfo = userService.getById(userId);
        String token = TokenUtils.sign(userInfo.getOpenId());
        return Result.success(token);
    }

    //新增和修改
    @PostMapping("/addAndUpdateUser")
    public Result<Object> addAndUpdateUser(@RequestBody UserModel userModel, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String openId = TokenUtils.verify(token);
        UserModel userInfo = userService.getUserByOpenid(openId);
        if (userModel.getValue() != null) {
            userModel.setAreaCode(JSON.toJSONString(userModel.getValue()));
        }
        if (ObjectUtil.isEmpty(userModel)) {
            return Result.error(400, "参数错误");
        }


        if (ObjectUtil.isNotEmpty(userInfo)) {
            userModel.setUpdateTime(CommonHelp.getNowTimestamp());
            if (ObjectUtil.isNotNull(userModel.getName())) {
                userInfo.setName(userModel.getName());
            }
            if (ObjectUtil.isNotNull(userModel.getFaceUrl())) {
                userInfo.setFaceUrl(userModel.getFaceUrl());
            }
            userInfo.setCityId(userModel.getCityId());
            userInfo.setAreaId(userModel.getAreaId());
            CityModel cityModel = cityMapper.selectOne(new QueryWrapper<CityModel>().eq(StrUtil.isNotBlank(userModel.getCityId()), "city_id", userModel.getCityId()));
            String provinceId = cityModel.getProvinceId().toString();
            ArrayList<String> list = new ArrayList<>();
            list.add(provinceId);
            list.add(userModel.getCityId());
            list.add(userModel.getAreaId());
            userInfo.setAreaCode(JSON.toJSONString(list));

            userService.updateById(userInfo);

            if(userInfo.getVip()==1&&userInfo.getInvitationCode()!=null)
            {

                userInfo=this.userService.generateBeautifiedTwodimensionalCode(userInfo);

            }

            return Result.success("");//修改成功
        } else {
            userModel.setOpenId(openId);
            userModel.setCreateTime(CommonHelp.getNowTimestamp());
            userService.save(userModel);
            return Result.success("");//添加成功
        }

    }

    @Autowired
    private InvationCodeMapper invationCodeMapper;

    //小程序端登录后的查询个人信息
    @GetMapping("/getUserInfo")
    public Result<Object> getUserInfo(@RequestParam(value = "phone", required = false) String phone, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(mobile);
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        if (user.getCityId() != null) {
            CityModel cityModel = cityMapper.selectOne(new QueryWrapper<CityModel>()
                    .eq("city_id", user.getCityId()));
            String city = cityModel.getCity();
            user.setCityName(city);
        }
        if (user.getAreaId() != null) {
            AreaModel areaModel = areaMapper.selectOne(new QueryWrapper<AreaModel>()
                    .eq("area_id", user.getAreaId()));
            String area = areaModel.getArea();
            user.setAreaName(area);
        }
        if(user.getVip()==1)
        {
            if(StrUtil.isBlankIfStr(user.getBeautifyAccountsCodeUrl())||StrUtil.isBlankIfStr(user.getBeautifyInvitationCodeUrl()))
            {
                user=this.userService.generateBeautifiedTwodimensionalCode(user);
            }
        }

        QueryWrapper<AddressModel> addressModelQueryWrapper = new QueryWrapper<>();
        addressModelQueryWrapper.eq("is_default", 1);
        addressModelQueryWrapper.eq("user_id", user.getId());
        AddressModel addressModel = addressService.getOne(addressModelQueryWrapper);
        user.setAddressModel(addressModel);
        if (user.getCustomerServiceId() != null) {
            CustomerServiceModel serviceModel = customerServiceService.getById(user.getCustomerServiceId());
            user.setCustomerServiceModel(serviceModel);
        }
        user.setOpenId(null);
        if (user.getPaymentPassword() == null) {
            user.setIsPassword(2);
        } else {
            user.setIsPassword(1);
        }
        return Result.success(user);
    }

    //
    //退出
    @PostMapping("/logout")
    public Result<Object> logout(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(mobile);

        CacheUtil.remove(user.getOpenId());

        return Result.success("");//退出成功
    }

    //升级会员
    @PostMapping("/upVip")
    public Result upVip(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String orderSn = IdUtil.fastSimpleUUID();
        String openId = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(openId);//转账方
        Integer userId = user.getId();
        String ip = IpUtil.getIpAddress(request);

        Object o = userService.upVip(orderSn, user.getLoginOpenid(), ip,user,userId);
        return Result.success(o);
    }

    @GetMapping("/message")
    public Result message(){
        this.smsUtils.sendSmsVerificationCode("13591814579","12345");
        return Result.success("fasongchenggon ");
    }

    /**
     * 转账
     *
     * @param invitationCode 邀请码
     * @param request        请求
     * @return {@link Result}<{@link Object}>
     */
    @GetMapping("/transferAccounts")
    public Result transferAccounts(String invitationCode,
                                   Double transferAmount,
                                   HttpServletRequest request,
                                   String paymentPassword) {
        if (ObjectUtil.isNull(invitationCode)) {
            return Result.error(400, "请填写转帐对象");
        }
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);//当前用户
        UserModel user = userService.getUserByOpenid(mobile);//转账方
        if (StrUtil.isBlankIfStr(user.getAreaId()) || StrUtil.isBlankIfStr(user.getCityId())) {
            return Result.error(201, "请先在个人资料设置所属区域");
        }

        UserModel beneficiary = new UserModel();//收钱方
        if (StrUtil.isNotBlank(invitationCode)) {
            beneficiary = userService.getUserByInviteCodeOrPhone(invitationCode);
            if(beneficiary==null)
            {
                return Result.error(201, "抱歉,没有找到该用户");
            }
        }

        if (StrUtil.isBlankIfStr(beneficiary.getAreaId()) || StrUtil.isBlankIfStr(beneficiary.getCityId())) {
            return Result.error(201, "对方未设置所属区域");
        }

        if (beneficiary.getVip() == 2) {
            return Result.error(201, "不能给非会员用户转账");
        }
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        if (StrUtil.isBlank(invitationCode)) {
            return Result.error(201, "请扫描正确的收款码或输入正确的手机号");
        }
        if (user.getPaymentPassword() == null) {
            return Result.error(201, "请设置支付密码");
        }
        if (user.getInvitationCode().equals(invitationCode)) {
            return Result.error(201, "不能给自己转账");
        }
        if (user.getId().equals(beneficiary.getId())) {
            return Result.error(201, "不能给自己转账");
        }
        if (user.getVip() == 2) {
            return Result.error(201, "非会员用户不能转账");
        }
        String newWord = md5Hex(paymentPassword + user.getSalt());
        if (!user.getPaymentPassword().equals(newWord)) {
            return Result.error(201, "支付密码错误");
        }
        if (user.getVoucher() < transferAmount) {
            return Result.error(201, "金额不足");
        }
        UserModel model = userService.isTransferAccounts(beneficiary, transferAmount, user);
        return Result.success(model);
    }
    @GetMapping("/manuallyAssignInvitationRelationships")
    public Result<Object> manuallyAssignInvitationRelationships(@RequestParam(value = "orderSn") String orderSn,
                                                                @RequestParam(value = "userId") Integer userId)
    {
        this.userService.manuallyAssignInvitationRelationships(orderSn,userId);
        return Result.success(null);
    }

    /**
     * 设置支付密码
     *
     * @param paymentPassword 支付密码
     * @param request         请求
     * @return {@link Result}<{@link Object}>
     */
    @GetMapping("/setPaymentPassword")
    public Result<Object> setPaymentPassword(String paymentPassword, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(mobile);
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        userService.setPaymentPassword(paymentPassword, user);
        return Result.success("");//设置成功
    }

    /**
     * 重置密码
     *
     * @param paymentPassword 支付密码
     * @param request         请求
     * @return {@link Result}<{@link Object}>
     */
    @GetMapping("/resetPassword")
    public Result<Object> resetPassword(String paymentPassword, String mobileCode, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(mobile);
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        Object code = this.redisService.getStringKey(SystemConstant.USER_CAPTCHA_CODE + user.getPhone());

        if (ObjectUtil.isEmpty(code)) {
            return Result.error(201, "手机号错误");
        }
        if (mobileCode.equals(code)) {
            this.redisService.deleteKey(SystemConstant.USER_CAPTCHA_CODE + user.getPhone());
            userService.setPaymentPassword(paymentPassword, user);
        }
        return Result.success("");//设置成功
    }

    /**
     * 发送验证码（图片）
     *
     * @return {@link Result}
     */
    @GetMapping("/sendVerificationCode")
    public Result sendVerificationCode(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String openId = TokenUtils.nothingness(token);

        UserModel user = userService.getUserByOpenid(openId);
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        if (!PhoneUtil.isMobile(user.getPhone())) {
            return Result.error(201, "手机号不正确");
        }
        if (this.redisService.existKey(SystemConstant.USER_PHONE_CODE + user.getPhone())) {
            return Result.error(201, "操作频繁,请超过2分钟后再试");
        }
        String authCode = RandomUtil.randomNumbers(5);
        this.smsUtils.sendSmsVerificationCode(user.getPhone(), authCode);
        this.redisService.setStringKey(SystemConstant.USER_CAPTCHA_CODE + user.getPhone(), authCode);
        this.redisService.setExpire(SystemConstant.USER_CAPTCHA_CODE + user.getPhone(), 60L, TimeUnit.SECONDS);
        return Result.success(null);
    }

    /**
     * 发送短信验证码
     *
     * @param request
     * @return 空
     */
    @GetMapping("/sendSMCode")
    public Result sendSMCode(HttpServletRequest request, @RequestParam(required = false) String phone) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        UserModel user = userService.getUserByOpenid(TokenUtils.nothingness(token));
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        if (ObjectUtil.isNull(phone)) {
            phone = user.getPhone();
        }
        if (!PhoneUtil.isMobile(phone)) {
            return Result.error(201, "手机号不正确");
        }
        if (this.redisService.existKey(SystemConstant.USER_PHONE_CODE + phone)) {
            return Result.error(201, "操作频繁,请超过2分钟后再试");
        }
        String authCode = RandomUtil.randomNumbers(5);
        this.smsUtils.sendSmsVerificationCode(phone, authCode);
        this.redisService.setStringKey(SystemConstant.USER_PHONE_CODE + phone, authCode);
        this.redisService.setExpire(SystemConstant.USER_PHONE_CODE + phone, 60L, TimeUnit.SECONDS);
        return Result.success(null);//短信验证码生成成功，并发送
    }

    /**
     * 是否转账账户
     *
     * @param invitationCode 邀请码
     * @param request        请求
     * @return {@link Result}<{@link Object}>
     */
    @GetMapping("/isTransferAccounts")
    public Result<Object> isTransferAccounts(String invitationCode, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(mobile);
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        if (user.getInvitationCode().equals(invitationCode)) {
            return Result.error(201, "不能给自己转账");
        }
        QueryWrapper<UserModel> userModelQueryWrapper = new QueryWrapper<>();
        userModelQueryWrapper.eq("invitation_code", invitationCode);
        UserModel model = userService.getOne(userModelQueryWrapper);
        return Result.success(DesensitizedUtil.mobilePhone(model.getPhone()));
    }


    /**
     * 获取他信息
     *
     * @param invitationCode 邀请码
     * @param request        请求
     * @return {@link Result}<{@link Object}>
     */
    @GetMapping("/getHeInfo")
    public Result<Object> getHeInfo(@RequestParam(value = "invitationCode", required = false) String invitationCode,
                                    HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(mobile);
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        if (user.getVip() == 2) {
            return Result.error(201, "请您先开通会员，再进行转账操作");
        }
        if (user.getInvitationCode().equals(invitationCode) || user.getPhone().equals(invitationCode)) {
            return Result.error(201, "不能给自己转账");
        }
        if (user.getPaymentPassword() == null) {
            return Result.error(201, "请设置支付密码");
        }
        QueryWrapper<UserModel> userModelQueryWrapper = new QueryWrapper<>();
        userModelQueryWrapper.select("name", "phone", "face_url");
        userModelQueryWrapper.eq("invitation_code", invitationCode).or().eq("phone", invitationCode);
        UserModel userModel = userMapper.selectOne(userModelQueryWrapper);
        if (userModel == null) {
            return Result.error(201, "用户不存在");
        }
        userModel.setPhone(DesensitizedUtil.mobilePhone(userModel.getPhone()));

        return Result.success(userModel);
    }

    /**
     * 更新用户头像
     *
     * @param faceUrl 人脸url
     * @return {@link Result}
     */
    @GetMapping("/updateUserFace")
    @Transactional(rollbackFor = Exception.class)
    public Result updateUserFace(String faceUrl, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(mobile);
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        String[] split = faceUrl.split("/");
        if (split.length > 0) {
            user.setFaceUrl(SystemConstant.DEFAULT_PDF_SERVICE_URL + split[split.length - 1]);
        }
        userService.updateById(user);
        return Result.success("");//操作成功
    }

    /**
     * 用户授权
     *
     * @param id            id
     * @param voucherAmount 凭证金额
     * @param request       请求
     * @return {@link Result}<{@link Object}>
     */
    @GetMapping("/userGrant")
    public Result<Object> userGrant(Integer id, Double voucherAmount, Double integral, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(405, "token不存在");
        }
        String userId = TokenUtils.verify(token);
        AdminUserModel user = adminUserService.getById(Integer.parseInt(userId));
        if (user == null) {
            return Result.error(405, "用户不存在");
        }
        userService.userGrant(id, voucherAmount, integral);
        return Result.success("");//修改成功
    }


    /**
     * 查询用户是否是刚刚成为会员
     */
    @GetMapping("/ifBecomeVipJustNow")
    public Result ifBecomeVipJustNow(HttpServletRequest request){
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error(StatusCodeEnum.STATUS405.getCode(), StatusCodeEnum.STATUS405.getMsg());
        }
        String mobile = TokenUtils.nothingness(token);
        UserModel user = userService.getUserByOpenid(mobile);
//        UserModel user = userService.getUserByPhone(mobile);
        if (user == null) {
            return Result.error(StatusCodeEnum.STATUS406.getCode(), StatusCodeEnum.STATUS406.getMsg());
        }
        return userService.ifBecomeVipJustNow(user);
    }

    /**
     * 数据修复
     */
//    @GetMapping("dataRepair")
//    @Transactional(rollbackFor = Exception.class)
//    public void dataRepair() throws Exception {
//        QueryWrapper<UserModel> userModelQueryWrapper = new QueryWrapper<>();
//        userModelQueryWrapper.eq("vip", 1);
//        userModelQueryWrapper.isNull("invitation_code");
//        List<UserModel> userModels = this.userService.list(userModelQueryWrapper);
//        for (UserModel user : userModels
//        ) {
//            //生成邀请码
//            String randomString = null;
//            try {
//                // 执行业务逻辑
//                int nextNumber = Integer.parseInt(invationCodeMapper.selectById(1).getInvationCode()) + 1;//邀请码
//                randomString = String.format("%08d", nextNumber);
//                InvitationCodeModel invitationCodeModel = new InvitationCodeModel();
//                invitationCodeModel.setInvationCode(randomString);
//                invitationCodeModel.setId(1);
//                invationCodeMapper.updateById(invitationCodeModel);//更新数据库当前邀请码
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//            //邀请二维码
//            user.setInvitationCode(randomString);
//            long l = System.currentTimeMillis();
//            user.setVipTime(new Timestamp(l));
//            String invitationCode = "type=1&" + randomString;
//            String invitationCodeFileUrl = System.getProperty("user.dir") + File.separator + "file" + File.separator + invitationCode + ".jpg";
//            WxQrCode.generateQrCode(invitationCodeFileUrl, "pages/index/index", WechatUtil.redisToken(), randomString);
//            user.setInvitationCodeUrl(DEFAULT_PDF_SERVICE_URL + invitationCode + ".jpg");
//            //转账二维码
//            String transferAccountsCode = "type=2&" + randomString;
//            String transferAccountsCodePath = System.getProperty("user.dir") + File.separator + "file" + File.separator + transferAccountsCode + ".png";
//            QrCodeUtil.generate(transferAccountsCode, 300, 300, FileUtil.file(transferAccountsCodePath));
//            user.setTransferAccountsCodeUrl(DEFAULT_PDF_SERVICE_URL + transferAccountsCode + ".png");
//            this.userService.updateById(user);
//        }
//    }


//    @GetMapping("generateUrl")
//    public void generateUrl()
//    {
//        QueryWrapper<UserModel> userModelQueryWrapper=new QueryWrapper<>();
//        userModelQueryWrapper.between("vip_time","2024-09-09 09:11:55",new Date());
//        userModelQueryWrapper.eq("vip",1);
//        userModelQueryWrapper.isNotNull("vip_time");
//        userModelQueryWrapper.ne("face_url","/file/IO4Tsg41.jpg");
//        List<UserModel> userModelList=this.userService.list(userModelQueryWrapper);
//        for (UserModel u:userModelList
//             ) {
//            try{
//                this.userService.regenerate(u);
//                this.userService.generateBeautifiedTwodimensionalCode(u);
//            }catch (Exception e)
//            {
//
//            }
//        }
//    }

}
